#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <ctime>
#define NUM 10
using namespace std;

void *threadRun(void *args)
{
    const char *name = static_cast<const char *>(args);

    int cnt = 5;
    while (cnt)
    {
        cout << name << " is runing: " << cnt-- << " obtain self id: " << pthread_self() << endl;
        sleep(1);
    }
    pthread_exit((void *)11);
}
int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, threadRun, (void *)"thread 1");

    // sleep(3);
    // 正在运行时，一个线程是可以被取消的
    // pthread_cancel(tid);//本来要跑5秒，但是只跑了3秒,可以看取消了哪些线程

    void *ret = nullptr;
    pthread_join(tid, &ret);

    cout << " new thread exit: " << (uint64_t)ret << " quit thread: " << tid << endl; // 强转int会有精度损失,由8变成4了
}

// enum
// {
//     OK = 0,
//     ERROR
// };

// class ThreadDate
// {
// public:
//     ThreadDate(const string &name, int id, time_t createTime, int top)
//         : _name(name), _id(id), _createTime((uint64_t)createTime), _status(OK), _top(top), _result(0)
//     {
//     }
//     ~ThreadDate()
//     {
//     }

// public:
//     // 输入的
//     string _name;
//     int _id;
//     uint64_t _createTime;

//     // 返回的
//     int _status;
//     int _top;
//     int _result;
//     // char arr[n];
// };

// // 线程终止
// // 1、线程函数执行完成,return void*
// // 2、pthread_exit(void*)
// void *thread_run(void *args)
// {
//     // char *name = (char *)args;

//     ThreadDate *td = static_cast<ThreadDate *>(args);

//     for (int i = 1; i <= td->_top; i++)
//     {
//         td->_result += i;
//     }
//     cout << td->_name << " cal done!" << endl;
//     pthread_exit(td); // 可换成return td

//     // exit(10); //直接退出了
//     // while (true)
//     //{
//     // cout << "main thread runing,my thread name is:" << name << endl;
//     // cout << "main thread runing, name:" << td->_name << " create time: " << td->_createTime << " index: " << td->_id << endl;
//     // sleep(4);

//     // exit(10);//只有一或二个等线程跑起来了，进程退出，不是线程退出，只要有任何一个线程调度exit，整个进程（所以线程）全部退出

//     // 线程函数执行完成
//     // break;
//     //}
//     // delete name;

//     // delete td;
//     //  pthread_exit(nullptr); // 终止对应线程

//     pthread_exit((void *)1); // 给退出信息，把1强转成void*,void *val=(void*)1;也可以
//     // return nullptr;
// }
// int main()
// {

//     pthread_t tids[NUM]; // 创建多个线程
//     for (int i = 0; i < NUM; i++)
//     {
//         // 解决名字一样的问题
//         char *tname = new char[64];
//         // bug?
//         // char tname[64];
//         snprintf(tname, 64, "thread-%d", i + 1); // 给每个线程一个名字,名字应该是1到10，但名字都是一样的，因为
//         ThreadDate *td = new ThreadDate(tname, i + 1, time(nullptr), 100 + i);
//         pthread_create(tids + i, nullptr, thread_run, td);
//         sleep(1);

//         // pthread_create(tids + i, nullptr, thread_run, tname);
//         //  pthread_create(tids + i, nullptr, thread_run, "thread1");
//     }

//     // 线程等待,等待新线程退出
//     void *ret = nullptr; // 是一个指针变量，要开空间，是有空间的，把线程退出信息放到ret中，int a = 30
//     for (int i = 0; i < NUM; i++)
//     {
//         // int n = pthread_join(tids[i], nullptr); // 等待每个线程的结果
//         int n = pthread_join(tids[i], &ret); // 接收线程退出信息
//         if (n != 0)
//             cerr << "pthread_join error" << endl;
//         // cout << "thread quit:" << (uint64_t)ret << endl;
//         ThreadDate *td = static_cast<ThreadDate *>(ret);
//         if (td->_status == OK)
//         {
//             cout << td->_name << "计算的结果是：" << td->_result << " (它要计算的是[1, " << td->_top << "])" << endl;
//         }
//     }

//     cout << "all thread quit.." << endl;

//     return 0; // 线程创建完后，就结束主线程，会发生什么呢？主线程退出，所以线程都会退出
//     // 主线程退出，相当于进程退出,所以主线程不要轻易退出

//     // 创建线程
//     // 主进程和线程谁先跑，不确定
//     // pthread_create(&t, nullptr, thread_run, nullptr);

//     // while (true)
//     //{
//     // cout << "main thread runing,new thread id:" << endl;
//     // sleep(1);
//     //}
//     // return 0;
// }